package com.atguigu.gulimall.product.service.impl;

import com.atguigu.common.utils.Query;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryBrandRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;

import com.atguigu.gulimall.product.dao.CategoryDao;
import com.atguigu.gulimall.product.service.CategoryService;
import org.springframework.transaction.annotation.Transactional;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Autowired
    CategoryBrandRelationService categoryBrandRelationService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<CategoryEntity> listToTree() {
        //查出所有菜单
        List<CategoryEntity> allCategory = baseMapper.selectList(null);
        //过滤出一级菜单并设置子菜单
        return allCategory.stream()
                        .filter(first -> first.getParentCid() == 0)
                        .peek((firstMenu)-> firstMenu.setChild(getChildMenu(firstMenu,allCategory)))
                        .sorted(Comparator.comparingInt(CategoryEntity::getSort))
                        .collect(Collectors.toList());
    }

    /** [2,23,122] 2->23->122
     * 根据 catelogId 找出他所有的路径节点id
     * @param catelogId 目录id
     * @return 节点id组成的数组
     */
    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> paths = new ArrayList<>();
        List<Long> parentsId = findParentsId(catelogId, paths);
        Collections.reverse(parentsId);
        return parentsId.toArray(new Long[parentsId.size()]);
    }

    /**
     * 级联更新字段，包含其他表的冗余字段
     * @param category
     */
    @Override
    @Transactional
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        categoryBrandRelationService.updateCategory(category.getCatId(),category.getName());
    }

    /** [122,23,2] 122->23->2
     * 根据 catelogId 递归找出他所有的父节点id
     * @param catelogId
     * @param paths
     * @return
     */
    private List<Long> findParentsId(Long catelogId,List<Long> paths ){
        paths.add(catelogId);
        CategoryEntity byId = this.getById(catelogId);
        if(byId.getParentCid() != 0){
            findParentsId(byId.getParentCid(),paths);
        }
        return paths;
    }

    /**
     * 根据rootMenu去找出所有菜单中的子菜单
     * @param rootMenu 父菜单
     * @param allMenu 所有菜单
     * @return 返回设置好子菜单的菜单列表
     */
    private List<CategoryEntity> getChildMenu(CategoryEntity rootMenu,List<CategoryEntity> allMenu){
        return allMenu.stream()
                // 过滤出所有allMenu的子菜单
                .filter(allItem -> (allItem.getParentCid()==null?0:allItem.getParentCid()) == (rootMenu.getCatId()==null?0:rootMenu.getCatId()) )
                // 将每个子菜单又递归去设置他们的子菜单
                .peek(all-> all.setChild(getChildMenu(all,allMenu)))
                // 对菜单排序
                .sorted(Comparator.comparingInt(CategoryEntity::getSort))
                .collect(Collectors.toList());
    }


}
